﻿using System;
using System.Drawing;

namespace NGridDrawer.Partitions
{
    /// <summary>
    /// Defines a drawer which is able to paint a grid of data
    /// </summary>
    public interface IPartitionDrawer
    {
        /// <summary>
        /// Draw the <paramref name="element"/> in the <paramref name="graphic"/>
        /// with <paramref name="clipBounds"/>.Location as a top left coordinate
        /// </summary>
        /// <param name="graphic">This is the graphics used to paint</param>
        /// <param name="clipBounds">This should be the maximum bounds of the element</param>
        /// <param name="element">This is the partition to paint</param>   
        void Paint(Graphics graphic, RectangleF clipBounds, PartitionElement element);


        ///<summary>
        /// Event raised when an element is gonna be drawn
        ///</summary>
        event EventHandler<ElementDrawnEventArgs> ElementDrawing;


        ///<summary>
        /// Event raised when an element has been drawn
        ///</summary>
        event EventHandler<ElementDrawnEventArgs> ElementDrawn;

        #region properties which define how to paint partitions

        /// <summary>
        /// Useful to define if partitions must be horizontally centered in their bounds when painted
        /// </summary>
        bool MustCenterHorizontally { get; set; }

        /// <summary>
        /// Useful to define if partitions must be vertically centered in their bounds when painted
        /// </summary>
        bool MustCenterVertically { get; set; }


        /// <summary>
        /// Useful to indicates the order in which partitions have to be painted
        /// </summary>
        PartitionOrder PrintOrder { get; set; }

        #endregion

        #region Needed methods to partition a grid of datas

        /// <summary>
        /// get the number of rows which will be painted
        /// </summary>
        int RowCount { get; }

        /// <summary>
        /// get the number of columns which will be painted
        /// </summary>
        int ColumnCount { get; }

        /// <summary>
        /// Calculate the columns header height of the grid of data</summary>
        /// <param name="graphic">graphics used to render the grid of data</param>
        /// <returns>The height of the columns header of the grid of data</returns>
        float GetHeaderHeight(Graphics graphic);

        /// <summary>
        /// Compute the width of the [row header] column
        /// </summary>
        /// <param name="graphic">graphics used to paint</param>
        /// <returns>float value, width applied the row headers</returns>
        float RowHeaderWidth(Graphics graphic);

        /// <summary>
        /// Get the height of a row
        /// </summary>
        /// <param name="graphic">graphics used to paint</param>
        /// <param name="rowKey">index of the interesting row</param>
        /// <returns>float value, height of the interesting row</returns>
        float RowHeight(Graphics graphic, int rowKey);


        /// <summary>
        /// Get the width of a column
        /// </summary>
        /// <param name="graphic">graphics used to paint</param>
        /// <param name="columnKey">index of the interesting column</param>
        /// <returns>float value, width of the interesting column</returns>
        float ColumnWidth(Graphics graphic, int columnKey);


        /// <summary>
        /// Partitions the grid of data into printable areas.
        /// </summary>
        /// <param name="graphic">graphics used to paint</param>
        /// <param name="clipHeights">defines the maximum bounds for height of each partitionLevel</param>
        /// <param name="clipWidths">defines the maximum bounds for width of each partitionColumn</param>
        /// <returns>A partition of the grid to paint</returns>
        /// <seealso cref="NGridDrawer.Partitions.PartitionGrid"/>
        PartitionGrid BuildPartition(Graphics graphic, float[] clipHeights, float[] clipWidths);

        #endregion
    }
}